package ch.ethz.fcl.metrobuzz.controller.gui.seekbar;

import java.io.IOException;

import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;

import ch.ethz.fcl.metrobuzz.controller.external.ActionEvent;
import ch.ethz.fcl.metrobuzz.controller.external.mouse.MouseEvent;
import ch.ethz.fcl.metrobuzz.controller.external.mouse.MouseListener;
import ch.ethz.fcl.metrobuzz.render.techniques.projection.Projection;
import ch.ethz.fcl.metrobuzz.spatialindex.object2d.Point2D;
import ch.ethz.fcl.metrobuzz.spatialindex.object2d.Rectangle;
import ch.ethz.fcl.metrobuzz.spatialindex.object3d.Point3D;

/**
 * Thumbs of seek bar contain normal and pressed texture handle whether these
 * thumbs are pressed
 * 
 * @author Zeng Wei
 * 
 */
public class SeekBarThumb {
	public static Texture thumbTexture;
	public static Texture thumbPressedTexture;

	private Texture selected;

	private float x, y;
	private float width, height;

	private Rectangle thumbArea;
	private Rectangle textureArea;

	private Rectangle bound;

	public SeekBarThumb() {
		try {
			if (thumbTexture == null)
				thumbTexture = TextureLoader.getTexture("PNG", ResourceLoader
						.getResourceAsStream("res/rsb/seek_thumb_normal.png"));
			if (thumbPressedTexture == null)
				thumbPressedTexture = TextureLoader
						.getTexture(
								"PNG",
								ResourceLoader
										.getResourceAsStream("res/rsb/seek_thumb_pressed.png"));
		} catch (IOException e) {
			e.printStackTrace();
		}

		GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
		selected = thumbTexture;

		width = thumbTexture.getImageWidth();
		height = thumbTexture.getImageHeight();
		validateArea();
	}

	public void setPosition(float x, float y) {
		this.x = x;
		this.y = (bound == null) ? y : Math.min(y, bound.getMaxY());
		this.y = (bound == null) ? this.y : Math.max(this.y, bound.getMinY());
		validateArea();
	}

	public void setBound(Rectangle rec) {
		this.bound = rec;
	}

	public Rectangle getTextureArea() {
		return textureArea;
	}

	public float getPosX() {
		return x;
	}

	public float getPosY() {
		return y;
	}

	public float getWidth() {
		return width;
	}

	public float getHeight() {
		return height * 3.4f / 8;
	}

	public void setWidth(float width) {
		float ratio = width / this.width;
		this.height *= ratio;
		this.width = width;
		validateArea();
	}

	public void setSize(float width, float height) {
		this.width = width;
		this.height = height;
		validateArea();
	}

	public Rectangle getThumbArea() {
		return thumbArea;
	}

	public void update(MouseEvent event) {
		if (event != null)
			handleEvent(event);

		render(selected);
	}

	private void handleEvent(MouseEvent event) {
		Projection proj = new Projection();
		Point3D mouseP = proj.getWorldCoord(
				new Point2D(Mouse.getX(), Mouse.getY()), 0);

		if ((event.getAction() == ActionEvent.ACTION_DOWN || event.getAction() == ActionEvent.ACTION_DRAG)
				&& thumbArea.contains(mouseP.getX(), mouseP.getY())) {
			MouseListener.update = false;
			// x += event.getDeltaX();
			y = event.getEventY();
			selected = thumbPressedTexture;
			validateArea();
		} else {
			MouseListener.update = true;
			selected = thumbTexture;
		}
	}

	private void validateArea() {
		thumbArea = new Rectangle(x, y, x + width, y + height * 3.4f / 8);
		textureArea = new Rectangle(x, y - height * 1.8f / 8, x + width, y
				+ 6.2f / 8 * height);
	}

	public void render(Texture selected) {
		GL11.glColor4f(1, 1, 1, 1);
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, selected.getTextureID());
		GL11.glBegin(GL11.GL_QUADS);

		GL11.glTexCoord2f(0, 0);
		GL11.glVertex2f(textureArea.getMinX(), textureArea.getMaxY());

		GL11.glTexCoord2f(1, 0);
		GL11.glVertex2f(textureArea.getMaxX(), textureArea.getMaxY());

		GL11.glTexCoord2f(1, 1);
		GL11.glVertex2f(textureArea.getMaxX(), textureArea.getMinY());

		GL11.glTexCoord2f(0, 1);
		GL11.glVertex2f(textureArea.getMinX(), textureArea.getMinY());
		GL11.glEnd();

		GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
	}
}
